package `01-agency`

import kotlin.properties.ReadOnlyProperty
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
 * 属性委托给类
 * 第二种：自定义委托类
 */

class TestAgency{
    /**
     * 将str的数据委托给CustomAgency类的实例
     * var 可读可写 被委托类需要实现setVaule和getVaule
     */
    var str:String by CustomAgencyString()

    var str02:String by CustomAgencyString02()

    /**
     * 将finalNum的数据委托给CustomInt类的实例
     * val 可读不可写 被委托类需要只实现getVaule即可
     */
    val finalNum:Int by CustomAgencyInt()

    val finalNum02:Int by CustomAgencyInt02()
}

/**
 * 第一种：自定义委托类，自己实现getValue和setValue方法
 */
class CustomAgencyString{
    var strData:String = "我是CustomAgency"

    /**
     * 自定义委托实现
     * 第一个参数是委托属性所在的类 TestAgency
     * 第二个参数是 KProperty<*> 固定
     * 返回值类型是委托属性的类型
     */
    operator fun getValue(any: Any, property: KProperty<*>): String {
        return strData
    }

    /**
     * 自定义委托实现
     * 第一个参数是委托属性所在的类 TestAgency
     * 第二个参数是 KProperty<*> 固定
     * 第三个参数是 要设置的数据
     */
    operator fun setValue(any: Any, property: KProperty<*>, s: String) {
        strData = s
    }
}

/**
 * 第二种：自定义委托类，继承ReadWriteProperty接口
 * ReadWriteProperty接口有两个泛型，
 * 第一个是委托属性所在的类及其父类（TestAgency/Any）
 * 第二个是委托属性的类型
 *
 * 好处：getValue和setValue方法通过继承ReadWriteProperty接口实现
 */
class CustomAgencyString02:ReadWriteProperty<Any,String>{
    var strData:String = "我是CustomAgency02"
    override fun getValue(thisRef: Any, property: KProperty<*>): String {
        return strData
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: String) {
        strData = value
    }

}

/**
 * 第一种：自定义委托类
 */
class CustomAgencyInt {
    operator fun getValue(testAgency: TestAgency, property: KProperty<*>): Int {
        return 10
    }
}

/**
 * 第二种：自定义委托类 通过继承ReadOnlyProperty实现
 */
class CustomAgencyInt02:ReadOnlyProperty<Any,Int> {
    override fun getValue(thisRef: Any, property: KProperty<*>): Int {
        return 20
    }

}

fun main() {
    var testAgency = TestAgency()

    println(testAgency.str)
    testAgency.str = "我是CustomAgency修改过后的数据"
    println(testAgency.str)
    println(testAgency.str02)

    println()
    println(testAgency.finalNum)
    println(testAgency.finalNum02)
}